/*
单例基类
*/

export abstract class Singleton<T extends Singleton<T>> {
  private static _instances: Map<Function, any> = new Map();
  public static getInstance<T extends Singleton<T>>(this: { prototype: T }): T {
    const Ctor = this as unknown as new () => T;

    if (!Singleton._instances.has(Ctor)) {
      Singleton._instances.set(Ctor, new Ctor());
    }
    return Singleton._instances.get(Ctor)! as T;
  }

  protected constructor() {
    const Ctor = this.constructor as typeof Singleton;

    if (Ctor !== Singleton && Singleton._instances.has(Ctor)) {
      throw new Error(
        `Singleton class "${Ctor.name}" cannot be instantiated more than once.`
      );
    }

    Singleton._instances.set(Ctor, this);
  }
}
